package yicheng.dinnertogetherapp;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.Format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeSet;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.amazonaws.util.StringUtils;

import yicheng.dinnertogetherapp.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class FriendListActivity extends ListActivity{
	ListView friendList_listView;
	LinearLayout friendList_loading_layout;

	private SwipeRefreshLayout friendList_refreshLayout;
	
	AmazonClientManager clientManager;

	SharedPreferences local_user_information;
	SharedPreferences.Editor local_user_editor;
	String PREFS_NAME = "LocalUserInfo";

	public static HashMap<String, String> onlineFriendList, offlineFriendList;

	String[] onlineFriendNames, onlineFriendNumbers;
	String[] offlineFriendNames, offlineFriendNumbers;
	String[] friendListNames, friendListNumbers;

	String [] onlineFriendPhotoUrl;
	String [] offlineFriendPhotoUrl;
	
	String[] onlineFriendAvailability;


	String PHONE_NUMBER;

	int chosenPostion;

	String chosenFriendPhoneNumber;
	String chosenFriendNickname;

	Handler handler;

	/*	ArrayAdapter<String> adapter;*/
	private  HomeListAdapter HomeListAdapter;
	private SeparatedListAdapter adapter; 
	private ArrayList<HomeItem> HomeItemList;


	/*	private MyCustomAdapter myAdapter;*/

	boolean isFriendListLoaded;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);

		clientManager = new AmazonClientManager();

		setContentView(R.layout.friendlist_view);

		local_user_information =  this.getSharedPreferences(PREFS_NAME,0);

		friendList_loading_layout = (LinearLayout) findViewById(R.id.friendList_loading_view_layout);
		
		friendList_refreshLayout = (SwipeRefreshLayout) findViewById(R.id.friendList_refreshLayout);
				

		if (isConnectedToInternet()){
			loadFriendList();
			friendList_loading_layout.setVisibility(View.VISIBLE);
		}
		else{
			Toast.makeText(getApplicationContext(), "You are not conneceted to Internet, please check.", Toast.LENGTH_SHORT).show();
		}




		handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				if (msg.what == 1){

					//set true when database is loaded 
					isFriendListLoaded = true;
					if (isFriendListLoaded){
						friendList_listView = (ListView) findViewById(android.R.id.list);

						/*
						adapter = new ArrayAdapter<String>(FriendListActivity.this,
								android.R.layout.simple_list_item_1, android.R.id.text1, friendListNames){

							@Override
							public View getView(int position,
									View convertView, ViewGroup parent) {

								// TODO Auto-generated method stub
								View view = super.getView(position, convertView, parent);

								TextView textView = (TextView) view.findViewById(android.R.id.text1);

								if (position < onlineFriendNames.length){
									textView.setTextColor(Color.BLACK);
								}
								else{
									textView.setTextColor(Color.GRAY);
								}


								return view;
							}

						};




						friendList_listView.setAdapter(adapter);*/








						sortByStartTime();

						/*	
						myAdapter = new MyCustomAdapter();

						myAdapter.addSeparatorItem("People who want to eat");

						for (int i = 1; i < onlineFriendNames.length; i++){
							myAdapter.addItem(onlineFriendNames[i], "haha");

						}

						myAdapter.addSeparatorItem("People who want to sleep");

						for (int i = 1; i < offlineFriendNames.length; i++){
							myAdapter.addItem(offlineFriendNames[i], "");
						}

						friendList_listView.setAdapter(myAdapter);*/







						PopulateHomePageItemList();









						friendList_loading_layout.setVisibility(View.INVISIBLE);

						friendList_listView.setOnItemClickListener(new ListView.OnItemClickListener(){

							@Override
							public void onItemClick(AdapterView<?> parent,
									View view, int position, long id) {
								// TODO Auto-generated method stub

								//position = position + 1;






								if (position != 0 && position != onlineFriendNames.length){
									boolean isAvailable = (position < onlineFriendNames.length) ? true : false;

									Bundle data_bundle = new Bundle();

									if (position < onlineFriendNames.length){
										data_bundle.putString("myFriendName", onlineFriendNames[position]);

										data_bundle.putString("myFriendNumber", onlineFriendNumbers[position]);

										data_bundle.putBoolean("isFriendAvailableToMe", isAvailable);
									}
									else if (position > onlineFriendNames.length){
										data_bundle.putString("myFriendName", offlineFriendNames[position - onlineFriendNames.length ]);

										data_bundle.putString("myFriendNumber", offlineFriendNumbers[position - onlineFriendNames.length ]);

										data_bundle.putBoolean("isFriendAvailableToMe", isAvailable);
									}

									Intent gotoFriendInfoActivity = new Intent("yicheng.dinnertogetherapp.FRIENDINFOACTIVITY");
									gotoFriendInfoActivity.putExtra("friendInformation", data_bundle);
									startActivity(gotoFriendInfoActivity);
								}




							}

						});
					}

					//set loading spinner invisble when database is loaded
					if (friendList_refreshLayout.isRefreshing()){
						friendList_refreshLayout.setRefreshing(false);
						friendList_refreshLayout.setEnabled(true);
					}

				}


				/*	if (msg.what == 2){
					addFriend_loading_layout.setVisibility(View.INVISIBLE);
					adapter.remove(adapter.getItem(chosenPostion));
					adapter.notifyDataSetChanged();
					Toast.makeText(getApplicationContext(), "Add friend successfully!", Toast.LENGTH_SHORT).show();
				}*/



			}
		};


		setRefreshLayoutControl();




	}

	private void setRefreshLayoutControl(){
		friendList_refreshLayout.setColorScheme(android.R.color.darker_gray, 
				android.R.color.holo_orange_light, 
				android.R.color.darker_gray, 
				android.R.color.holo_green_dark);
		friendList_refreshLayout.setOnRefreshListener(new OnRefreshListener(){

			@Override
			public void onRefresh() {
				// TODO Auto-generated method stub

				friendList_refreshLayout.setEnabled(false);
				friendList_refreshLayout.setRefreshing(true);
				if (isConnectedToInternet()){
					loadFriendList();
					friendList_loading_layout.setVisibility(View.VISIBLE);
				}
				else{
					Toast.makeText(getApplicationContext(), "You are not conneceted to Internet, please check.", Toast.LENGTH_SHORT).show();
				}
			}

		});
	}


	private void loadFriendList(){
		PHONE_NUMBER = local_user_information.getString("PhoneNumber", "default");
		runOnUiThread(new Runnable(){

			@Override
			public void run() {
				// TODO Auto-generated method stub
				new Thread(new Runnable(){

					@Override
					public void run() {
						// TODO Auto-generated method stub

						onlineFriendList = SimpleDB.getAttributesForItem(clientManager, PHONE_NUMBER, SimpleDB.ONLINE_FRIEND_LIST_ITEM);
						offlineFriendList = SimpleDB.getAttributesForItem(clientManager, PHONE_NUMBER, SimpleDB.OFFLINE_FRIEND_LIST_ITEM);

						onlineFriendList.remove("2060000000");
						onlineFriendList.remove("Name");

						offlineFriendList.remove("2060000000");
						offlineFriendList.remove("Name");

						//onlineFriendNumbers = new String[](onlineFriendList.keySet().toArray());
						String [] tempOnlineFriendNumbers =  onlineFriendList.keySet().toArray(new String[0]);
						String [] tempOnlineFriendNames =  onlineFriendList.values().toArray(new String[0]);

						String [] tempOfflineFriendNumbers =  offlineFriendList.keySet().toArray(new String[0]);
						String [] tempOfflineFriendNames =  offlineFriendList.values().toArray(new String[0]);

						onlineFriendNumbers = new String[tempOnlineFriendNumbers.length+1];
						onlineFriendNames = new String[tempOnlineFriendNames.length+1];

						offlineFriendNumbers = new String[tempOfflineFriendNumbers.length+1];
						offlineFriendNames = new String[tempOfflineFriendNames.length+1];

						onlineFriendPhotoUrl= new String[onlineFriendNames.length];
						offlineFriendPhotoUrl = new String[offlineFriendNames.length];
						
						
						for (int i = 1; i < tempOnlineFriendNumbers.length+1; i++){
							onlineFriendNumbers[i] = tempOnlineFriendNumbers[i-1];

						}

						onlineFriendAvailability = new String[tempOnlineFriendNumbers.length+1];

						for (int i = 1; i < onlineFriendNumbers.length; i++){
							onlineFriendAvailability[i] = SimpleDB.getSingleAttributesForItem(clientManager, onlineFriendNumbers[i], SimpleDB.AVAILABILITY_ITEM, SimpleDB.START_TIME_ATTRIBUTE);
						}

						for (int i = 1; i < tempOnlineFriendNames.length+1; i++){
							onlineFriendNames[i] = tempOnlineFriendNames[i-1];
						}


						for (int i = 1; i < tempOfflineFriendNumbers.length+1; i++){
							offlineFriendNumbers[i] = tempOfflineFriendNumbers[i-1];
						}

						for (int i = 1; i < tempOfflineFriendNames.length+1; i++){
							offlineFriendNames[i] = tempOfflineFriendNames[i-1];
						}
						
						for (int i = 1; i < onlineFriendNumbers.length; i++){
							onlineFriendPhotoUrl[i] = SimpleDB.getSingleAttributesForItem(clientManager, onlineFriendNumbers[i], SimpleDB.PHOTO_URL_ITEM, SimpleDB.PHOTO_URL_ATTRIBUTE);
						}
						
						for (int i = 1; i < offlineFriendNumbers.length; i++){
							offlineFriendPhotoUrl[i] = SimpleDB.getSingleAttributesForItem(clientManager, offlineFriendNumbers[i], SimpleDB.PHOTO_URL_ITEM, SimpleDB.PHOTO_URL_ATTRIBUTE);
						}
						

						/*friendListNumbers = new String[onlineFriendNumbers.length + offlineFriendNumbers.length];
						friendListNames = new String[onlineFriendNames.length + offlineFriendNames.length];

						ArrayList<String> tempFriendListNumbers = new ArrayList<String>(onlineFriendNumbers.length + offlineFriendNumbers.length);
						ArrayList<String> tempFriendListNames = new ArrayList<String>(onlineFriendNames.length + offlineFriendNames.length);

						Collections.addAll(tempFriendListNumbers, onlineFriendNumbers);
						Collections.addAll(tempFriendListNumbers, offlineFriendNumbers);

						Collections.addAll(tempFriendListNames, onlineFriendNames);
						Collections.addAll(tempFriendListNames, offlineFriendNames);

						friendListNumbers = tempFriendListNumbers.toArray(new String[0]);
						friendListNames = tempFriendListNames.toArray(new String[0]);
						 */

						//loadFriendPhoto();

						Message msg = Message.obtain();
						msg.what = 1;
						handler.sendMessage(msg);



					}

				}).start();
			}

		});
	}



















	@Override
	public void onBackPressed() {
		// TODO Auto-generated method stub
		moveTaskToBack(true);
	}



	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		if (keyCode == KeyEvent.KEYCODE_BACK ) {
			//preventing default implementation previous to 
			//android.os.Build.VERSION_CODES.ECLAIR
			moveTaskToBack(true);

			return false;
		}     
		return super.onKeyDown(keyCode, event);    

	}


	private boolean isConnectedToInternet(){
		ConnectivityManager connectivityManager = 
				(ConnectivityManager)FriendListActivity.this.getSystemService(Context.CONNECTIVITY_SERVICE);

		NetworkInfo wifi_network = 
				connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
		NetworkInfo mobile_network = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);


		//Only for testing
		return wifi_network.isConnectedOrConnecting() || mobile_network.isConnectedOrConnecting();

		/*	return mobile_network.isConnectedOrConnecting();*/

	}

	private ArrayList<Date> onlineFriendStartTimeList;

	private HashMap<Date, Integer> map = new HashMap<Date, Integer>();

	private void sortByStartTime(){
		//onlineFriendNames
		//onlineFriendAvailability
		onlineFriendStartTimeList = new ArrayList<Date>();
		for (int i = 1; i < onlineFriendAvailability.length; i++){
			Date start_date = new Date();
			try {
				start_date = new SimpleDateFormat("EE, yy/MM/dd h:mm a", Locale.getDefault()).parse(onlineFriendAvailability[i]);
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			map.put(start_date, i);
			
			onlineFriendStartTimeList.add(start_date);
		}
		
		


		Collections.sort(onlineFriendStartTimeList, new Comparator<Date>() {
			@Override
			public int compare(Date lhs, Date rhs) {
				if (lhs.getTime() < rhs.getTime())
					return -1;
				else if (lhs.getTime() == rhs.getTime())
					return 0;
				else
					return 1;
			}
		});

		String [] dummyOnlineFriendNames = new String[onlineFriendNames.length];
		for (int i = 1; i < onlineFriendNames.length; i++){
			dummyOnlineFriendNames[i] = onlineFriendNames[i];
		}
		
		String [] dummyOnlineFriendPhotoUrl = new String[onlineFriendPhotoUrl.length];
		for (int i = 1; i < onlineFriendPhotoUrl.length; i++){
			dummyOnlineFriendPhotoUrl[i] = onlineFriendPhotoUrl[i];
		}

		for (int i = 1; i < onlineFriendAvailability.length; i++){
			Format formatter = new SimpleDateFormat("EE, yy/MM/dd h:mm a");
			String dateString = formatter.format(onlineFriendStartTimeList.get(i-1));
			onlineFriendAvailability[i] = dateString;
			onlineFriendNames[i] = dummyOnlineFriendNames[map.get(onlineFriendStartTimeList.get(i-1))];
			onlineFriendPhotoUrl[i] = dummyOnlineFriendPhotoUrl[map.get(onlineFriendStartTimeList.get(i-1))];
		}



	}


	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
/*
		if (isConnectedToInternet()){
			loadFriendList();

		}
		else{
			Toast.makeText(getApplicationContext(), "You are not conneceted to Internet, please check.", Toast.LENGTH_SHORT).show();
		}*/




		/*		handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				if (msg.what == 1){

					//set true when database is loaded 
					isFriendListLoaded = true;
					if (isFriendListLoaded){
						friendList_listView = (ListView) findViewById(R.id.friendList_listView);


						adapter = new ArrayAdapter<String>(FriendListActivity.this,
								android.R.layout.simple_list_item_1, android.R.id.text1, friendListNames){

							@Override
							public View getView(int position,
									View convertView, ViewGroup parent) {

								// TODO Auto-generated method stub
								View view = super.getView(position, convertView, parent);

								TextView textView = (TextView) view.findViewById(android.R.id.text1);

								if (position < onlineFriendNames.length){
									textView.setTextColor(Color.BLACK);
								}
								else{
									textView.setTextColor(Color.GRAY);
								}


								return view;
							}

						};




						friendList_listView.setAdapter(adapter);

						friendList_loading_layout.setVisibility(View.INVISIBLE);

						friendList_listView.setOnItemClickListener(new ListView.OnItemClickListener(){

							@Override
							public void onItemClick(AdapterView<?> parent,
									View view, int position, long id) {
								// TODO Auto-generated method stub

								boolean isAvailable = (position < onlineFriendNames.length) ? true : false;


								Bundle data_bundle = new Bundle();
								data_bundle.putString("myFriendName", friendListNames[position]);

								data_bundle.putString("myFriendNumber", friendListNumbers[position]);

								data_bundle.putBoolean("isFriendAvailableToMe", isAvailable);

								Intent gotoFriendInfoActivity = new Intent("com.example.dinnertogetherapp.FRIENDINFOACTIVITY");
								gotoFriendInfoActivity.putExtra("friendInformation", data_bundle);
								startActivity(gotoFriendInfoActivity);







							}

						});
					}

					//set loading spinner invisble when database is loaded


				}


					if (msg.what == 2){
					addFriend_loading_layout.setVisibility(View.INVISIBLE);
					adapter.remove(adapter.getItem(chosenPostion));
					adapter.notifyDataSetChanged();
					Toast.makeText(getApplicationContext(), "Add friend successfully!", Toast.LENGTH_SHORT).show();
				}



			}
		};*/





	}




















	/*	

	private class MyCustomAdapter extends BaseAdapter {

		private static final int TYPE_ITEM = 0;
		private static final int TYPE_SEPARATOR = 1;
		private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1;

		private ArrayList<String> nameList = new ArrayList<String>();
		private ArrayList<String> endTimeList = new ArrayList<String>();


		private LayoutInflater myInflater;

		private TreeSet<Integer> mySeparatorSet = new TreeSet<Integer>();

		public MyCustomAdapter(){
			myInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

		}

		public void addItem(final String name, final String time){
			nameList.add(name);
			endTimeList.add(time);

			notifyDataSetChanged();
		}

		public void addSeparatorItem(final String item){
			nameList.add(item);

			mySeparatorSet.add(nameList.size()-1);
			notifyDataSetChanged();

		}

		@Override
		public int getItemViewType(int position){
			return mySeparatorSet.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;			
		}

		@Override
		public int getViewTypeCount(){
			return TYPE_MAX_COUNT;
		}

		@Override
		public int getCount() {
			return nameList.size();
		}

		@Override
		public Object getItem(int position) {
			return nameList.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder holder = null;
			int type = getItemViewType(position);
			if (convertView == null){
				holder = new ViewHolder();
				switch (type) {
				case TYPE_ITEM:
					convertView = myInflater.inflate(R.layout.friend_list_item_layout, null);
					holder.name_textView = (TextView) convertView.findViewById(R.id.friend_list_item_textView);
					holder.endTime_textView = (TextView) convertView.findViewById(R.id.friend_list_item_time_textView);

					break;

				case TYPE_SEPARATOR:
					convertView = myInflater.inflate(R.layout.friend_list_header_layout, null);
					holder.name_textView = (TextView) convertView.findViewById(R.id.friend_list_header_textView);

					break;
				}
				convertView.setTag(holder);
			}
			else{
				holder = (ViewHolder) convertView.getTag();
			}
			holder.name_textView.setText(nameList.get(position));
			holder.endTime_textView.setText(endTimeList.get(position));
			return convertView;
		}
	}



	public static class ViewHolder{
		public TextView name_textView;
		public TextView endTime_textView;
	}




	 */
	/*myAdapter = new MyCustomAdapter();

	myAdapter.addSeparatorItem("People who want to eat");

	for (int i = 1; i < onlineFriendNames.length; i++){
		myAdapter.addItem(onlineFriendNames[i], "haha");

	}

	myAdapter.addSeparatorItem("People who want to sleep");

	for (int i = 1; i < offlineFriendNames.length; i++){
		myAdapter.addItem(offlineFriendNames[i], "");
	}

	friendList_listView.setAdapter(myAdapter);
	 */







	private void PopulateHomePageItemList(){
		adapter = new SeparatedListAdapter(this);

		HomeItemList = new ArrayList<HomeItem>();
		for(int i = 1; i < onlineFriendNames.length; i++){
			HomeItem homeItem = new HomeItem();
			homeItem.setHomeItemID(i);
			homeItem.setHomeItemName(onlineFriendNames[i]);
			homeItem.setHomeItemDescription(onlineFriendAvailability[i]);
			homeItem.setImageUrl(onlineFriendPhotoUrl[i]);
			//homeItem.setImageUrl("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQBcE1SdhbR-3HCNtqQ13rw0GiatdcE7hBwpgF9h56dHPXuXTCmDA");
			HomeItemList.add(homeItem);
		}
		HomeListAdapter = new  HomeListAdapter(getApplicationContext(), 0, HomeItemList);
		if(HomeListAdapter!= null)
			adapter.addSection(" People who want to eat ", HomeListAdapter );


		HomeItemList = new ArrayList<HomeItem>();
		for(int i = 1; i < offlineFriendNames.length; i++){
			HomeItem homeItem = new HomeItem();
			homeItem.setHomeItemID(i);
			homeItem.setHomeItemName(offlineFriendNames[i]);
			homeItem.setHomeItemDescription("");
			homeItem.setImageUrl(offlineFriendPhotoUrl[i]);
		    //homeItem.setImageUrl("https://www.google.co.in/images/srpr/logo4w.png");
			HomeItemList.add(homeItem);
		}
		HomeListAdapter = new  HomeListAdapter(getApplicationContext(), 0, HomeItemList);
		if(HomeListAdapter!= null)
			adapter.addSection(" People who want to sleep ", HomeListAdapter );



		friendList_listView.setAdapter(adapter);
	}











	public class HomeListAdapter extends ArrayAdapter<HomeItem> implements OnClickListener {
		public Context context;
		public ArrayList<HomeItem> HomeItemList;
		public ImageLoader imageLoader;

		public HomeListAdapter(Context context, int resource, ArrayList<HomeItem> HomeItemLst) {
			super(context, resource, HomeItemLst);
			this.context = context;
			this.HomeItemList = HomeItemLst;
			imageLoader = new ImageLoader(context);
		}

		@Override
		public int getCount() {
			if (HomeItemList != null)
				return HomeItemList.size();

			return 0;
		}

		@Override
		public HomeItem getItem(int position) {
			return HomeItemList.get(position);
		}

		@Override
		public View getView(final int position, View convertView, ViewGroup parent) {
			View myConvertView = null;
			try {
				final HomeItem HomeItem = HomeItemList.get(position);
				myConvertView = convertView;
				if (myConvertView == null) {
					LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
					myConvertView = inflater.inflate(R.layout.friend_list_item_layout, null);
				}
				ImageView CatImage = (ImageView) myConvertView.findViewById(R.id.friend_list_item_imageView);
				TextView CatHeader = (TextView) myConvertView.findViewById(R.id.friend_list_item_textView);
				TextView CatTitle = (TextView) myConvertView.findViewById(R.id.friend_list_item_time_textView);

				CatHeader.setText(HomeItem.getHomeItemName());
				CatTitle.setText(HomeItem.getHomeItemDescription());

				imageLoader.DisplayImage(HomeItem.getImageUrl(), CatImage);

			} catch (Exception e) {
				e.printStackTrace();
			}
			return myConvertView;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		public void onClick(View v) {
			// TODO Auto-generated method stub

		}

	}

















	public class SeparatedListAdapter extends BaseAdapter
	{
		public final Map<String, Adapter> sections = new LinkedHashMap<String, Adapter>();
		public final ArrayAdapter<String> headers;
		public final static int TYPE_SECTION_HEADER = 0;

		public SeparatedListAdapter(Context context)
		{
			headers = new ArrayAdapter<String>(context, R.layout.friend_list_header_layout);
		}

		public void addSection(String section, Adapter adapter)
		{
			this.headers.add(section);
			this.sections.put(section, adapter);
		}

		public Object getItem(int position)
		{
			for (Object section : this.sections.keySet())
			{
				Adapter adapter = sections.get(section);
				int size = adapter.getCount() + 1;

				// check if position inside this section
				if (position == 0) return section;
				if (position < size) return adapter.getItem(position - 1);

				// otherwise jump into next section
				position -= size;
			}
			return null;
		}

		public int getCount()
		{
			// total together all sections, plus one for each section header
			int total = 0;
			for (Adapter adapter : this.sections.values())
				total += adapter.getCount() + 1;
			return total;
		}

		@Override
		public int getViewTypeCount()
		{
			// assume that headers count as one, then total all sections
			int total = 1;
			for (Adapter adapter : this.sections.values())
				total += adapter.getViewTypeCount();
			return total;
		}

		@Override
		public int getItemViewType(int position)
		{
			int type = 1;
			for (Object section : this.sections.keySet())
			{
				Adapter adapter = sections.get(section);
				int size = adapter.getCount()+1;

				// check if position inside this section
				if (position == 0) return TYPE_SECTION_HEADER;
				if (position < size) return type + adapter.getItemViewType(position - 1);

				// otherwise jump into next section
				position -= size;
				type += adapter.getViewTypeCount();
			}
			return -1;
		}

		public boolean areAllItemsSelectable()
		{
			return false;
		}

		@Override
		public boolean isEnabled(int position)
		{
			return (getItemViewType(position) != TYPE_SECTION_HEADER);
		}

		public View getView(int position, View convertView, ViewGroup parent)
		{
			int sectionnum = 0;
			for (Object section : this.sections.keySet())
			{
				Adapter adapter = sections.get(section);
				int size = adapter.getCount() + 1;

				// check if position inside this section
				if (position == 0) return headers.getView(sectionnum, convertView, parent);
				if (position < size) return adapter.getView(position - 1, convertView, parent);

				// otherwise jump into next section
				position -= size;
				sectionnum++;
			}
			return null;
		}

		public long getItemId(int position)
		{
			return position;
		}

	}














	public class HomeItem {
		private String ImageUrl;
		private int HomeItemID;
		private String HomeItemName;
		private String HomeItemDescription;


		public String getImageUrl() {
			return ImageUrl;
		}
		public void setImageUrl(String imageUrl) {
			this.ImageUrl = imageUrl;
		}

		public int getHomeItemID() {
			return HomeItemID;
		}
		public void setHomeItemID(int ID) {
			this.HomeItemID = ID;
		}

		public String getHomeItemName() {
			return HomeItemName;
		}
		public void setHomeItemName(String Name) {
			this.HomeItemName = Name;
		}


		public String getHomeItemDescription() {
			return HomeItemDescription;
		}
		public void setHomeItemDescription(String Description) {
			this.HomeItemDescription = Description;
		}

	}



	public class ImageLoader {
		MemoryCache memoryCache=new MemoryCache();
		FileCache fileCache;
		private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
		ExecutorService executorService;
		Handler handler=new Handler();//handler to display images in UI thread

		public ImageLoader(Context context){
			fileCache=new FileCache(context);
			executorService=Executors.newFixedThreadPool(5);
		}

		final int stub_id=R.drawable.ic_launcher;
		public void DisplayImage(String url, ImageView imageView)
		{
			imageViews.put(imageView, url);
			Bitmap bitmap=memoryCache.get(url);
			if(bitmap!=null)
				imageView.setImageBitmap(bitmap);
			else
			{
				queuePhoto(url, imageView);
				imageView.setImageResource(stub_id);
			}
		}

		private void queuePhoto(String url, ImageView imageView)
		{
			PhotoToLoad p=new PhotoToLoad(url, imageView);
			executorService.submit(new PhotosLoader(p));
		}

		private Bitmap getBitmap(String url) 
		{
			File f=fileCache.getFile(url);

			//from SD cache
			Bitmap b = decodeFile(f);
			if(b!=null)
				return b;

			//from web
			try {
				Bitmap bitmap=null;
				URL imageUrl = new URL(url);
				HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
				conn.setConnectTimeout(30000);
				conn.setReadTimeout(30000);
				conn.setInstanceFollowRedirects(true);
				InputStream is=conn.getInputStream();
				OutputStream os = new FileOutputStream(f);
				Utils.CopyStream(is, os);
				os.close();
				conn.disconnect();
				bitmap = decodeFile(f);
				return bitmap;
			} catch (Throwable ex){
				ex.printStackTrace();
				if(ex instanceof OutOfMemoryError)
					memoryCache.clear();
				return null;
			}
		}

		//decodes image and scales it to reduce memory consumption
		private Bitmap decodeFile(File f){
			try {
				//decode image size
				BitmapFactory.Options o = new BitmapFactory.Options();
				o.inJustDecodeBounds = true;
				FileInputStream stream1=new FileInputStream(f);
				BitmapFactory.decodeStream(stream1,null,o);
				stream1.close();

				//Find the correct scale value. It should be the power of 2.
				final int REQUIRED_SIZE=70;
				int width_tmp=o.outWidth, height_tmp=o.outHeight;
				int scale=1;
				while(true){
					if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
						break;
					width_tmp/=2;
					height_tmp/=2;
					scale*=2;
				}

				//decode with inSampleSize
				BitmapFactory.Options o2 = new BitmapFactory.Options();
				o2.inSampleSize=scale;
				FileInputStream stream2=new FileInputStream(f);
				Bitmap bitmap=BitmapFactory.decodeStream(stream2, null, o2);
				stream2.close();
				return bitmap;
			} catch (FileNotFoundException e) {
			} 
			catch (IOException e) {
				e.printStackTrace();
			}
			return null;
		}

		//Task for the queue
		private class PhotoToLoad
		{
			public String url;
			public ImageView imageView;
			public PhotoToLoad(String u, ImageView i){
				url=u; 
				imageView=i;
			}
		}

		class PhotosLoader implements Runnable {
			PhotoToLoad photoToLoad;
			PhotosLoader(PhotoToLoad photoToLoad){
				this.photoToLoad=photoToLoad;
			}

			public void run() {
				try{
					if(imageViewReused(photoToLoad))
						return;
					Bitmap bmp=getBitmap(photoToLoad.url);
					memoryCache.put(photoToLoad.url, bmp);
					if(imageViewReused(photoToLoad))
						return;
					BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);
					handler.post(bd);
				}catch(Throwable th){
					th.printStackTrace();
				}
			}
		}

		boolean imageViewReused(PhotoToLoad photoToLoad){
			String tag=imageViews.get(photoToLoad.imageView);
			if(tag==null || !tag.equals(photoToLoad.url))
				return true;
			return false;
		}

		//Used to display bitmap in the UI thread
		class BitmapDisplayer implements Runnable
		{
			Bitmap bitmap;
			PhotoToLoad photoToLoad;
			public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;}
			public void run()
			{
				if(imageViewReused(photoToLoad))
					return;
				if(bitmap!=null)
					photoToLoad.imageView.setImageBitmap(bitmap);
				else
					photoToLoad.imageView.setImageResource(stub_id);
			}
		}

		public void clearCache() {
			memoryCache.clear();
			fileCache.clear();
		}

	}











	public class FileCache {

		private File cacheDir;

		public FileCache(Context context){
			//Find the dir to save cached images
			if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
				cacheDir=new File(android.os.Environment.getExternalStorageDirectory(), "LazyList");
			else
				cacheDir=context.getCacheDir();
			if(!cacheDir.exists())
				cacheDir.mkdirs();
		}

		public File getFile(String url){
			//I identify images by hashcode. Not a perfect solution, good for the demo.
			String filename=String.valueOf(url.hashCode());
			//Another possible solution (thanks to grantland)
			//String filename = URLEncoder.encode(url);
			File f = new File(cacheDir, filename);
			return f;

		}

		public void clear(){
			File[] files=cacheDir.listFiles();
			if(files==null)
				return;
			for(File f:files)
				f.delete();
		}

	}




	public class MemoryCache {
		private static final String TAG = "MemoryCache";
		private Map<String, Bitmap> cache=Collections.synchronizedMap(
				new LinkedHashMap<String, Bitmap>(10,1.5f,true));//Last argument true for LRU ordering
		private long size=0;//current allocated size
		private long limit=1000000;//max memory in bytes

		public MemoryCache(){
			//use 25% of available heap size
			setLimit(Runtime.getRuntime().maxMemory()/4);
		}

		public void setLimit(long new_limit){
			limit=new_limit;
			Log.i(TAG, "MemoryCache will use up to "+limit/1024./1024.+"MB");
		}

		public Bitmap get(String id){
			try{
				if(!cache.containsKey(id))
					return null;
				//NullPointerException sometimes happen here http://code.google.com/p/osmdroid/issues/detail?id=78 
				return cache.get(id);
			}catch(NullPointerException ex){
				ex.printStackTrace();
				return null;
			}
		}

		public void put(String id, Bitmap bitmap){
			try{
				if(cache.containsKey(id))
					size-=getSizeInBytes(cache.get(id));
				cache.put(id, bitmap);
				size+=getSizeInBytes(bitmap);
				checkSize();
			}catch(Throwable th){
				th.printStackTrace();
			}
		}

		private void checkSize() {
			Log.i(TAG, "cache size="+size+" length="+cache.size());
			if(size>limit){
				Iterator<Entry<String, Bitmap>> iter=cache.entrySet().iterator();//least recently accessed item will be the first one iterated  
				while(iter.hasNext()){
					Entry<String, Bitmap> entry=iter.next();
					size-=getSizeInBytes(entry.getValue());
					iter.remove();
					if(size<=limit)
						break;
				}
				Log.i(TAG, "Clean cache. New size "+cache.size());
			}
		}

		public void clear() {
			try{
				//NullPointerException sometimes happen here http://code.google.com/p/osmdroid/issues/detail?id=78 
				cache.clear();
				size=0;
			}catch(NullPointerException ex){
				ex.printStackTrace();
			}
		}

		long getSizeInBytes(Bitmap bitmap) {
			if(bitmap==null)
				return 0;
			return bitmap.getRowBytes() * bitmap.getHeight();
		}
	}











	public static class Utils {

		public static void CopyStream(InputStream is, OutputStream os)
		{
			final int buffer_size=1024;
			try
			{
				byte[] bytes=new byte[buffer_size];
				for(;;)
				{
					int count=is.read(bytes, 0, buffer_size);
					if(count==-1)
						break;
					os.write(bytes, 0, count);
				}
			}
			catch(Exception ex){}
		}
	}






	private void loadFriendPhoto(){

	

		// TODO Auto-generated method stub
		AmazonS3Client s3Client = new AmazonS3Client(new BasicAWSCredentials( PropertyLoader.getInstance().getAccessKey(), PropertyLoader.getInstance().getSecretKey() ) );      

		List<Bucket> listOfBucket = s3Client.listBuckets();

		Bucket photo_bucket = listOfBucket.get(2);

		/*	ObjectListing photoListInBucket = s3Client.listObjects(photo_bucket.getName());*/

		for (int i = 1; i < onlineFriendNumbers.length; i++){
			/*
			boolean isBucketContainsPhoto = false;
			for (S3ObjectSummary objectSummary : photoListInBucket.getObjectSummaries()){
				if (objectSummary.getKey().equals(onlineFriendNumbers[i])){
					isBucketContainsPhoto = true;
					break;
				}


			}

			 */
			/*	GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(photo_bucket.getName(), onlineFriendNumbers[i]);

			onlineFriendPhotoUrl[i] = s3Client.generatePresignedUrl( request ).toString();*/

			URL currentUrl = s3Client.getUrl(photo_bucket.getName(), onlineFriendNumbers[i]);

			onlineFriendPhotoUrl[i] = currentUrl.toString();
			/*
			s3Client.getUrl(photo_bucket.getName(), onlineFriendNumbers[i]);*/


		}



		for (int i = 1; i < offlineFriendNumbers.length; i++){
			/*	GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(photo_bucket.getName(), offlineFriendNumbers[i]);

			offlineFriendPhotoUrl[i] = s3Client.generatePresignedUrl( request ).toString();

			s3Client.getUrl(photo_bucket.getName(), offlineFriendNumbers[i]);
			 */

			
			
			URL currentUrl = s3Client.getUrl(photo_bucket.getName(), offlineFriendNumbers[i]);

			Log.d("get url", currentUrl.toString());
			
			offlineFriendPhotoUrl[i] = currentUrl.toString();


		}



	}


}
